package com.sz.common.base.dao.utils;

import com.sz.common.base.dao.annotation.JudgeEntity;
import com.sz.common.base.dao.annotation.Table;
import com.sz.common.base.dao.annotation.UniqueField;
import com.sz.common.base.entity.EntityBase;
import com.sz.common.base.exception.CommonErrorCodes;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.logger.Logger;


import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;


/**
 * Function: SqlUtil<br>
 * Author: hpeng.wang <br>
 * Date: 2016-11-01 14:11:00
 */
public class SqlUtil {
    private static Logger logger = Logger.getLogger(SqlUtil.class);

    /**
     * 获取一个实体类中的所有字段
     *
     * @param po
     * @return
     */
    public static Map<String, Serializable> getPramList(EntityBase po) {
        Map<String, Serializable> map = new HashMap<>();
        Class<? extends EntityBase> thisClass = po.getClass();
        Field[] fields = thisClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String fName = field.getName();
            Serializable value;
            try {
                value = (Serializable) field.get(po);
                field.setAccessible(false);
                if (Number.class.isAssignableFrom(field.getType())) {
                    if (value != null && ((Number) value).longValue() > 0) {
                        map.put(fName, value);
                    }
                    continue;
                }
            } catch (Exception e) {
                logger.error("参数解析异常", e);
                throw new RuntimeException("参数解析异常", e);
            }
            map.put(fName, value);
        }
        return map;
    }


    /**
     * 获取一个实体类对应的数据库表名
     *
     * @param po
     * @return
     */
    public static String getTableName(EntityBase po) {
        Class<? extends EntityBase> c = po.getClass();
        if (c.isAnnotationPresent(Table.class)) {
            return c.getAnnotation(Table.class).name();
        }
        throw Exceptions.bizException(CommonErrorCodes.ERROR_ANNOTATION_EMPTY, "@Table");
    }


    public static Annotation getAnnotation(Class aClass, Class annotation) {
        if (!aClass.isAnnotationPresent(annotation)) {
            return null;
        }
        return aClass.getAnnotation(annotation);
    }


    public static String getTableName(Class clzz) {

        Table table = (Table) getAnnotation(clzz, Table.class);
        if (table == null) {
            return null;
        }
        return table.name();
    }


    /**
     * 获取实体上的fieldOfSelectConditions注解
     *
     * @param clzz
     * @return
     */
    public static JudgeEntity getConditions(Class clzz) {
        Annotation annotation = getAnnotation(clzz, JudgeEntity.class);
        if (annotation == null) {
            return null;
        } else {
            JudgeEntity cd = (JudgeEntity) annotation;
            return cd;
        }
    }

    /**
     * 获取实体上的fieldOfSelectConditions注解
     *
     * @param clzz
     * @return
     */
    public static UniqueField[] getUniqueField(Class clzz) {
        UniqueField[] uniqueFields = new UniqueField[0];
        JudgeEntity entity = getConditions(clzz);
        if (entity != null) {
            uniqueFields = entity.fieldOfSelectConditions();
        }
        return uniqueFields;
    }

    /**
     * 效验
     * @param str
     * @return
     */
    public static boolean valueValidate(String str) {
        str = str.toLowerCase();//统一转为小写
        String badStr = "'select|delete|sitename|net user|xp_cmdshell|and|exec|execute|insert|create|drop|table|from|grant|use|group_concat|column_name|information_schema.columns|table_schema|union|where|order|by|count|*|chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";//过滤掉的sql关键字，可以手动添加
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }

}
